/*
 * Dep.cpp
 *
 *  Created on: 2009-9-26
 *      Author: ws
 */

#include<iostream>


#include"Node.hpp"

#include"Value.hpp"

#include"Dep.hpp"

RegValue * Dep::get_from_value()
{
	RegValue * regvalue =  RegValue_cast(from->get_value(this->from_loc));
	assert(regvalue != NULL);
	return regvalue;
}

RegValue * Dep::get_to_value()
{
	RegValue* regvalue = RegValue_cast(to->get_value(this->to_loc));
	assert(regvalue != NULL);
	return regvalue;
}


enum DType Dep::get_dep_type(enum LOC_Type from_type , enum LOC_Type to_type)
{
	if( from_type == DEST_MEM && to_type == SRC_MEM)
		return MEM_RAW;
	if( from_type == DEST_MEM && to_type == DEST_MEM)
		return MEM_WAW;
	if( from_type == SRC_MEM && to_type == DEST_MEM)
		return MEM_WAR;
	if( (from_type == SRC || from_type == IMPLICT_SRC) &&
	    (to_type == DEST || to_type == IMPLICT_DEST))
		return WAR;
	if( (from_type == DEST || from_type == IMPLICT_DEST ) &&
	    (to_type == SRC || to_type == IMPLICT_SRC))
		return RAW;
	if( (from_type == DEST || from_type == IMPLICT_DEST) &&
	    (to_type == DEST || to_type == IMPLICT_DEST) )
		return WAW;
	if((from_type == CTR)&& (to_type == DEST_MEM || to_type == SRC_MEM))
		return CTR_MEM;
	if((from_type == DEST_MEM || from_type == SRC_MEM) && (to_type == CTR))
		return MEM_CTR;
	if((from_type == CTR) && (to_type == CTR))
		return CTR_CTR;
	if((from_type == FACK) || (to_type == FACK))
		return FACK_DEP;

	assert("Region::get_dep_type(...): error"==" unexpected dep type");
}

Dep::Dep(Node &from,	location from_loc,  Node& to, location to_loc ):
	from_loc(from_loc), to_loc(to_loc), from(&from), to(&to)
{
	assert(from.get_value(from_loc)->get_id() == to.get_value(to_loc)->get_id());	
	value_id = from.get_value(from_loc)->get_id();
	//build DUChain
	type_flag = get_dep_type(from_loc.operand_type, to_loc.operand_type);
	switch (type_flag)
	{
	//the FACK_DEP for end_node and start_node, because start_node
	//have live_in reg, end_node have live_out reg; so the Dep
	//with live_in/out is 2 , so the fack_Dep is 2
	//TODO the pre_schedule may have impact on the current schedule
	case ::FACK_DEP:
		weight = 2;
		break;
	case ::CTR_MEM://from br to no_br
		weight = 1;
		break;
	case ::MEM_CTR:
		weight = 0;
		break;
	case ::CTR_CTR:
		weight = 1;
		break;
	case ::RAW:
		weight = 2;
		break;
	case ::WAR:
		weight = 0;
		break;
	case ::WAW:
		//at the pre_schedule ,the WAW Dep is not exit!!!!
		weight = 1;
		break;
	case ::MEM_RAW:
		weight = 0;
		break;
	case ::MEM_WAW:
		weight = 1;
		break;
	case ::MEM_WAR:
		weight = 1;
		break;
	default :
		assert("DAG::new_Dep: the unexpected Dep type is come up" == NULL);
	}
#if 0
cout<<"from "<<d->from->id<<" to "<<d->to->id<<" latency "<<d->weight<<endl;
#endif
}




bool Dep::is_visited()const
{
	return visited;
}
void Dep::set_visisted()
{
	visited = true;
}
void Dep::reset_visited()
{
	visited = false;
}

std::string Dep::get_dep_name()const
{
	switch(type_flag	)
	{
	case RAW:
			return std::string("RAW");
	case MEM_RAW:
			return std::string("MEM_RAW");
	case WAW:
			return std::string("WAW");
	case MEM_WAW:
			return std::string("MEM_WAW");
	case WAR:
			return std::string("WAR");
	case MEM_WAR:
			return std::string("MEM_WAR");
	case CTR_CTR:
			return std::string("CTR_CTR");
	case CTR_MEM:
			return std::string("CTR_MEM");
	case MEM_CTR:
			return std::string("MEM_CTR");
	case FACK_DEP:
			return std::string("FACK_DEP");
	default:
		assert("get_dep_name(): error"== "the type_flag is not expected!!!");
	}
}


void Dep::print()
{
}



